#pragma once
#include <cstddef>
#include <cstdlib>
#include<iostream>
#include <string>
#include<string.h>
#include <type_traits>

namespace ns_protocol
{
#define SPACE " "
#define SPACE_LEN strlen(SPACE)
#define SEP "\r\n"
#define SEP_LEN strlen(SEP) // 不能是sizeof！

class Request
{
public:
    std::string Serialize()
    {
        std::string str;
        str+=std::to_string(_x);
        str+=SPACE;
        str+=std::to_string(_y);
        str+=SPACE;
        return str;
    }
    //数据发送方要能够将数据重新解析出来
    // bool Deserialize(const std::string& str)
    // {
    //     std::size_t left=str.find(SPACE);
    //     if(left==std::string::npos){
    //         return false;
    //     }
    //     std::size_t right=str.rfind(SPACE);
    //     if(right==std::string::npos){
    //         return false;
    //     }
    //     _x=atoi(str.substr(0,left).c_str());
    //     _y=atoi(str.substr(right,right+SPACE_LEN).c_str());
    //     if(left+SPACE_LEN>str.size()){
    //         return false;
    //     }
    //     else{
    //         _op=str[left+SPACE_LEN];
    //     }
    //     return true;
    // }
    bool Desrialize(const std::string& str)
    {
        std::size_t left=str.find(SPACE);
        if(left==std::string::npos){
            return false;
        }
        std::size_t right=str.rfind(SPACE);
        if(right==std::string::npos){
            return false;
        }
        _x=atoi(str.substr(0,left).c_str());
        _y=atoi(str.substr(right+SPACE_LEN).c_str());
        if(left+str.size()){
            return false;
        }
        else{
            _op=str[left+SPACE_LEN];
        }
        return true;
    }
    // bool Desrialize(const std::string& str)
    // {
    //     std::size_t left=str.find(SPACE);
    //     if(left==std::string::npos){
    //         return false;
    //     }
    //     std::size_t right=str.rfind(SPACE);
    //     if(right==std::string::npos){
    //         return false;
    //     }
    //     _x=atoi(str.substr(0,left).c_str());
    //     //直接越过这一个空格取这单个字符
    //     _y=atoi(str.substr(right+SPACE_LEN).c_str());
    //     if(left+SPACE_LEN>str.size()){
    //         return false;
    //     }
    //     else{
    //         _op=str[left+SPACE_LEN];
    //     }
    //     return true;
    // }
public:
    Request(){}
    Request(int x,int y,char op)
    :_x(x),_y(y),_op(op)
    {

    }
    int _x;
    int _y;
    char _op;
};

class Response
{
public:
    std::string Serialize()
    {
        std::string s;
        s=std::to_string(_code);
        s+=SPACE_LEN;
        s+=std::to_string(_result);
        return s;
    }
    bool Deserialize(const std::string& str)
    {
        std::size_t pos=str.find(SPACE);
        if(pos==std::string::npos){
            return false;
        }
        _code=atoi(str.substr(0,pos).c_str());
        _result=atoi(str.substr(pos+SPACE_LEN).c_str());
        return true;
    }
    // bool Deserialize(const std::string& str)
    // {
    //     std::size_t pos=str.find(SPACE);
    //     if(pos==std::string::npos){
    //         return false;
    //     }
    //     _code=atoi(str.substr(0,pos).c_str());
    //     _result=atoi(str.substr(pos+SPACE_LEN).c_str());
    //     return true;
    // }
    // bool Desrialize(const std::string& str)
    // {
    //     std::size_t pos=str.find(SPACE);
    //     if(pos==std::string::npos){
    //         return false;
    //     }
    //     _code=atoi(str.substr(0,pos).c_str());
    //     _result=atoi(str.substr(pos+SPACE_LEN).c_str());
    //     return true;
    // }
public:
    int _x;
    int _y;
    char _op;
    int _result;
    int _code;
};
}